home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / PIL / OleFileIO.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  11KB  |  366 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import string
  5. import StringIO
  6.  
  7. def i16(c, o = 0):
  8.     return ord(c[o]) + (ord(c[o + 1]) << 8)
  9.  
  10.  
  11. def i32(c, o = 0):
  12.     return ord(c[o]) + (ord(c[o + 1]) << 8) + (ord(c[o + 2]) << 16) + (ord(c[o + 3]) << 24)
  13.  
  14. MAGIC = '\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1'
  15. VT_EMPTY = 0
  16. VT_NULL = 1
  17. VT_I2 = 2
  18. VT_I4 = 3
  19. VT_R4 = 4
  20. VT_R8 = 5
  21. VT_CY = 6
  22. VT_DATE = 7
  23. VT_BSTR = 8
  24. VT_DISPATCH = 9
  25. VT_ERROR = 10
  26. VT_BOOL = 11
  27. VT_VARIANT = 12
  28. VT_UNKNOWN = 13
  29. VT_DECIMAL = 14
  30. VT_I1 = 16
  31. VT_UI1 = 17
  32. VT_UI2 = 18
  33. VT_UI4 = 19
  34. VT_I8 = 20
  35. VT_UI8 = 21
  36. VT_INT = 22
  37. VT_UINT = 23
  38. VT_VOID = 24
  39. VT_HRESULT = 25
  40. VT_PTR = 26
  41. VT_SAFEARRAY = 27
  42. VT_CARRAY = 28
  43. VT_USERDEFINED = 29
  44. VT_LPSTR = 30
  45. VT_LPWSTR = 31
  46. VT_FILETIME = 64
  47. VT_BLOB = 65
  48. VT_STREAM = 66
  49. VT_STORAGE = 67
  50. VT_STREAMED_OBJECT = 68
  51. VT_STORED_OBJECT = 69
  52. VT_BLOB_OBJECT = 70
  53. VT_CF = 71
  54. VT_CLSID = 72
  55. VT_VECTOR = 4096
  56. VT = { }
  57. for k, v in vars().items():
  58.     if k[:3] == 'VT_':
  59.         VT[v] = k
  60.     
  61.  
  62. WORD_CLSID = '00020900-0000-0000-C000-000000000046'
  63.  
  64. class _OleStream(StringIO.StringIO):
  65.     
  66.     def __init__(self, fp, sect, size, offset, sectorsize, fat):
  67.         data = []
  68.         while sect != -2:
  69.             fp.seek(offset + sectorsize * sect)
  70.             data.append(fp.read(sectorsize))
  71.             sect = fat[sect]
  72.         data = string.join(data, '')
  73.         StringIO.StringIO.__init__(self, data[:size])
  74.  
  75.  
  76.  
  77. class _OleDirectoryEntry:
  78.     
  79.     def __init__(self, sidlist, sid):
  80.         (name, type, sect, size, sids, clsid) = sidlist[sid]
  81.         self.sid = sid
  82.         self.name = name
  83.         self.type = type
  84.         self.sect = sect
  85.         self.size = size
  86.         self.clsid = clsid
  87.         self.kids = []
  88.         sid = sidlist[sid][4][2]
  89.         if sid != -1:
  90.             stack = [
  91.                 self.sid]
  92.             (left, right, child) = sidlist[sid][4]
  93.             while left != -1:
  94.                 stack.append(sid)
  95.                 sid = left
  96.                 (left, right, child) = sidlist[sid][4]
  97.             while sid != self.sid:
  98.                 self.kids.append(_OleDirectoryEntry(sidlist, sid))
  99.                 (left, right, child) = sidlist[sid][4]
  100.                 if right != -1:
  101.                     sid = right
  102.                     while None:
  103.                         (left, right, child) = sidlist[sid][4]
  104.                         if left == -1:
  105.                             break
  106.                         
  107.                         sid = left
  108.                         continue
  109.                         continue
  110.                         while None:
  111.                             ptr = stack[-1]
  112.                             del stack[-1]
  113.                             (left, right, child) = sidlist[ptr][4]
  114.                             if right != sid:
  115.                                 break
  116.                             
  117.                             sid = right
  118.                             continue
  119.                             (left, right, child) = sidlist[sid][4]
  120.                             if right != ptr:
  121.                                 sid = ptr
  122.                                 continue
  123.                     self.kids.sort()
  124.                 
  125.  
  126.     
  127.     def __cmp__(self, other):
  128.         return cmp(self.name, other.name)
  129.  
  130.     
  131.     def dump(self, tab = 0):
  132.         TYPES = [
  133.             '(invalid)',
  134.             '(storage)',
  135.             '(stream)',
  136.             '(lockbytes)',
  137.             '(property)',
  138.             '(root)']
  139.         print ' ' * tab + repr(self.name), TYPES[self.type],
  140.         if self.type in (2, 5):
  141.             print self.size, 'bytes',
  142.         
  143.         print 
  144.         if self.type in (1, 5) and self.clsid:
  145.             print ' ' * tab + '{%s}' % self.clsid
  146.         
  147.         for kid in self.kids:
  148.             kid.dump(tab + 2)
  149.         
  150.  
  151.  
  152.  
  153. class OleFileIO:
  154.     
  155.     def __init__(self, filename = None):
  156.         if filename:
  157.             self.open(filename)
  158.         
  159.  
  160.     
  161.     def open(self, filename):
  162.         if type(filename) == type(''):
  163.             self.fp = open(filename, 'rb')
  164.         else:
  165.             self.fp = filename
  166.         header = self.fp.read(512)
  167.         if len(header) != 512 or header[:8] != MAGIC:
  168.             raise IOError, 'not an OLE2 structured storage file'
  169.         
  170.         clsid = self._clsid(header[8:24])
  171.         self.sectorsize = 1 << i16(header, 30)
  172.         self.minisectorsize = 1 << i16(header, 32)
  173.         self.minisectorcutoff = i32(header, 56)
  174.         self.loadfat(header)
  175.         self.loaddirectory(i32(header, 48))
  176.         self.ministream = None
  177.         self.minifatsect = i32(header, 60)
  178.  
  179.     
  180.     def loadfat(self, header):
  181.         sect = header[76:512]
  182.         fat = []
  183.         for i in range(0, len(sect), 4):
  184.             ix = i32(sect, i)
  185.             if ix == -2 or ix == -1:
  186.                 break
  187.             
  188.             s = self.getsect(ix)
  189.             fat = fat + map((lambda i, s = s: i32(s, i)), range(0, len(s), 4))
  190.         
  191.         self.fat = fat
  192.  
  193.     
  194.     def loadminifat(self):
  195.         s = self._open(self.minifatsect).read()
  196.         self.minifat = map((lambda i, s = s: i32(s, i)), range(0, len(s), 4))
  197.  
  198.     
  199.     def getsect(self, sect):
  200.         self.fp.seek(512 + self.sectorsize * sect)
  201.         return self.fp.read(self.sectorsize)
  202.  
  203.     
  204.     def _unicode(self, s):
  205.         return filter(ord, s)
  206.  
  207.     
  208.     def loaddirectory(self, sect):
  209.         fp = self._open(sect)
  210.         self.sidlist = []
  211.         while None:
  212.             entry = fp.read(128)
  213.             if not entry:
  214.                 break
  215.             
  216.             type = ord(entry[66])
  217.             name = self._unicode(entry[0:0 + i16(entry, 64)])
  218.             ptrs = (i32(entry, 68), i32(entry, 72), i32(entry, 76))
  219.             sect = i32(entry, 116)
  220.             size = i32(entry, 120)
  221.             clsid = self._clsid(entry[80:96])
  222.             continue
  223.             self.root = _OleDirectoryEntry(self.sidlist, 0)
  224.             return None
  225.  
  226.     
  227.     def dumpdirectory(self):
  228.         self.root.dump()
  229.  
  230.     
  231.     def _clsid(self, clsid):
  232.         if clsid == '\x00' * len(clsid):
  233.             return ''
  234.         
  235.         return ('%08X-%04X-%04X-%02X%02X-' + '%02X' * 6) % ((i32(clsid, 0), i16(clsid, 4), i16(clsid, 6)) + tuple(map(ord, clsid[8:16])))
  236.  
  237.     
  238.     def _list(self, files, prefix, node):
  239.         prefix = prefix + [
  240.             node.name]
  241.         for entry in node.kids:
  242.             if entry.kids:
  243.                 self._list(files, prefix, entry)
  244.                 continue
  245.             files.append(prefix[1:] + [
  246.                 entry.name])
  247.         
  248.  
  249.     
  250.     def _find(self, filename):
  251.         node = self.root
  252.         for name in filename:
  253.             for kid in node.kids:
  254.                 if kid.name == name:
  255.                     break
  256.                     continue
  257.             else:
  258.                 raise IOError, 'file not found'
  259.             node = kid
  260.         
  261.         return node.sid
  262.  
  263.     
  264.     def _open(self, start, size = 2147483647):
  265.         if size < self.minisectorcutoff:
  266.             if not self.ministream:
  267.                 self.loadminifat()
  268.                 self.ministream = self._open(self.sidlist[0][2])
  269.             
  270.             return _OleStream(self.ministream, start, size, 0, self.minisectorsize, self.minifat)
  271.         
  272.         return _OleStream(self.fp, start, size, 512, self.sectorsize, self.fat)
  273.  
  274.     
  275.     def listdir(self):
  276.         files = []
  277.         self._list(files, [], self.root)
  278.         return files
  279.  
  280.     
  281.     def openstream(self, filename):
  282.         slot = self._find(filename)
  283.         (name, type, sect, size, sids, clsid) = self.sidlist[slot]
  284.         if type != 2:
  285.             raise IOError, 'this file is not a stream'
  286.         
  287.         return self._open(sect, size)
  288.  
  289.     
  290.     def getproperties(self, filename):
  291.         fp = self.openstream(filename)
  292.         data = { }
  293.         s = fp.read(28)
  294.         clsid = self._clsid(s[8:24])
  295.         s = fp.read(20)
  296.         fmtid = self._clsid(s[:16])
  297.         fp.seek(i32(s, 16))
  298.         s = '****' + fp.read(i32(fp.read(4)) - 4)
  299.         for i in range(i32(s, 4)):
  300.             id = i32(s, 8 + i * 8)
  301.             offset = i32(s, 12 + i * 8)
  302.             type = i32(s, offset)
  303.             if type == VT_I2:
  304.                 value = i16(s, offset + 4)
  305.                 if value >= 32768:
  306.                     value = value - 65536
  307.                 
  308.             elif type == VT_UI2:
  309.                 value = i16(s, offset + 4)
  310.             elif type in (VT_I4, VT_ERROR):
  311.                 value = i32(s, offset + 4)
  312.             elif type == VT_UI4:
  313.                 value = i32(s, offset + 4)
  314.             elif type in (VT_BSTR, VT_LPSTR):
  315.                 count = i32(s, offset + 4)
  316.                 value = s[offset + 8:offset + 8 + count - 1]
  317.             elif type == VT_BLOB:
  318.                 count = i32(s, offset + 4)
  319.                 value = s[offset + 8:offset + 8 + count]
  320.             elif type == VT_LPWSTR:
  321.                 count = i32(s, offset + 4)
  322.                 value = self._unicode(s[offset + 8:offset + 8 + count * 2])
  323.             elif type == VT_FILETIME:
  324.                 value = long(i32(s, offset + 4)) + (long(i32(s, offset + 8)) << 32)
  325.                 value = value / 0x989680L
  326.             elif type == VT_UI1:
  327.                 value = ord(s[offset + 4])
  328.             elif type == VT_CLSID:
  329.                 value = self._clsid(s[offset + 4:offset + 20])
  330.             elif type == VT_CF:
  331.                 count = i32(s, offset + 4)
  332.                 value = s[offset + 8:offset + 8 + count]
  333.             else:
  334.                 value = None
  335.             data[id] = value
  336.         
  337.         return data
  338.  
  339.  
  340. if __name__ == '__main__':
  341.     import sys
  342.     for file in sys.argv[1:]:
  343.         
  344.         try:
  345.             ole = OleFileIO(file)
  346.             print '-' * 68
  347.             print file
  348.             print '-' * 68
  349.             ole.dumpdirectory()
  350.             for file in ole.listdir():
  351.                 if file[-1][0] == '\x05':
  352.                     print file
  353.                     props = ole.getproperties(file)
  354.                     props = props.items()
  355.                     props.sort()
  356.                     for k, v in props:
  357.                         print '   ', k, v
  358.                     
  359.                 
  360.         except IOError:
  361.             v = None
  362.             print '***', 'cannot read', file, '-', v
  363.  
  364.     
  365.  
  366.